package com.easylinkin.linkappapi.calculaterule.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.linkappapi.calculaterule.entity.CalculateConfig;
import com.easylinkin.linkappapi.calculaterule.entity.CalculateRule;
import com.easylinkin.linkappapi.calculaterule.entity.CalculateRuleAttribute;
import com.easylinkin.linkappapi.calculaterule.mapper.CalculateRuleMapper;
import com.easylinkin.linkappapi.calculaterule.service.CalculateConfigService;
import com.easylinkin.linkappapi.calculaterule.service.CalculateRuleAttributeService;
import com.easylinkin.linkappapi.calculaterule.service.CalculateRuleService;
import com.easylinkin.linkappapi.common.exceptions.BusinessException;
import com.easylinkin.linkappapi.common.service.CommonAdminService;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

/**
 * <p>
 * 计算规则  后台管理系统 服务实现类
 * </p>
 *
 * @author TongJie
 * @since 2020-06-17
 */
@Service
public class CalculateRuleServiceImpl extends ServiceImpl<CalculateRuleMapper, CalculateRule> implements CalculateRuleService {

    @Resource
    private CommonAdminService commonService;
    @Resource
    private CalculateRuleAttributeService calculateRuleAttributeService;
    @Resource
    private CalculateConfigService calculateConfigService;

    private static final Logger LOGGER = LoggerFactory.getLogger(CalculateRuleServiceImpl.class);

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean add(CalculateRule calculateRule) {
        validParamRequired(calculateRule);
        validParamFormat(calculateRule);
        validRepeat(calculateRule);
        commonService.setCreateAndModifyInfo(calculateRule);
        save(calculateRule);
        LOGGER.info("新增计算规则：{}", calculateRule.getName());

        List<CalculateRuleAttribute> calculateRuleAttributes = calculateRule.getCalculateRuleAttributes();

        for (CalculateRuleAttribute calculateConfigAttribute : calculateRuleAttributes) {
            calculateConfigAttribute.setCalculateRuleId(calculateRule.getId());
        }
        calculateRuleAttributeService.saveOrUpdateBatch(calculateRuleAttributes);

        return true;
    }

    /**
     * 校验重复
     */
    private void validRepeat(CalculateRule calculateRule) {
        QueryWrapper<CalculateRule> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", calculateRule.getName());
        List<CalculateRule> list = baseMapper.selectList(queryWrapper);
        if (list.size() == 0) {
            return;
        }
        if (list.size() > 1) {
            throw new BusinessException("规则名称有重复");
        }
        if (StringUtils.isEmpty(calculateRule.getId())) {
            throw new BusinessException("规则名称已存在");
        }
        if (!calculateRule.getId().equals(list.get(0).getId())) {
            throw new BusinessException("规则名称已存在");
        }
        
    }


    /**
     * 校验参数必填
     */
    private void validParamRequired(CalculateRule calculateRule) {

        Assert.notNull(calculateRule, "参数为空");
        Assert.isTrue(StringUtils.isNotBlank(calculateRule.getName()), "名称为空");
        Assert.isTrue(StringUtils.isNotBlank(calculateRule.getCode()), "编号为空");
    }

    /**
     * 校验参数格式
     */
    private void validParamFormat(CalculateRule calculateRule) {
        Assert.isTrue(calculateRule.getName() == null || calculateRule.getName().length() <= 32, "名称超长");
        Assert.isTrue(calculateRule.getCode() == null || calculateRule.getCode().length() <= 32, "编号超长");
    }

    @Override
    public List<CalculateRule> getCalculateRules(CalculateRule calculateRule) {
        QueryWrapper<CalculateRule> qw = new QueryWrapper<>();
        if (calculateRule != null && StringUtils.isNotEmpty(calculateRule.getName())) {
            qw.eq("name", calculateRule.getName());
        }
        return list(qw);
    }

    @Override
    public CalculateRule getCalculateRule(String id) {
        return baseMapper.getCalculateRule(id);
    }

    @Override
    public IPage<CalculateRule> getCalculateRulesPage(Page<CalculateRule> page, CalculateRule calculateRule) {
        QueryWrapper<CalculateRule> qw = new QueryWrapper<>();
        if (calculateRule != null && StringUtils.isNotEmpty(calculateRule.getName())) {
            qw.like("name", calculateRule.getName());
        }
        qw.orderByDesc("modify_time");
        return baseMapper.selectPage(page, qw);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateCalculateRule(CalculateRule calculateRule) {
        Assert.notNull(calculateRule, "参数为空");
        CalculateRule originCalculateRule = getById(calculateRule.getId());
        Assert.notNull(originCalculateRule, "原计算规则不存在");
        validRepeat(calculateRule);
        validParamFormat(calculateRule);
        commonService.setModifyInfo(calculateRule);
        updateById(calculateRule);

        List<CalculateRuleAttribute> calculateRuleAttributes = calculateRule.getCalculateRuleAttributes();
        Assert.notEmpty(calculateRuleAttributes, "计算规则属性列表不能为空");

        QueryWrapper<CalculateRuleAttribute> qw = new QueryWrapper<>();
        qw.eq("calculate_rule_id", calculateRule.getId());
        calculateRuleAttributeService.remove(qw);

        for (CalculateRuleAttribute calculateRuleAttribute : calculateRuleAttributes) {
            calculateRuleAttribute.setCalculateRuleId(calculateRule.getId());
        }
        calculateRuleAttributeService.saveBatch(calculateRuleAttributes);

        return true;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteBatch(List<CalculateRule> calculateRuleList) {
        Assert.notEmpty(calculateRuleList, "参数为空");
        List<String> ids = calculateRuleList.stream().map(CalculateRule::getId).collect(Collectors.toList());
        QueryWrapper<CalculateConfig> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("calculate_rule_id", ids);
        int count = calculateConfigService.count(queryWrapper);
        if (count > 0) {
            throw new BusinessException("要删除的计算规则被计算配置用到，不允许删除");
        }
        removeByIds(ids);
        return true;
    }

}

